package com.hk.Mgr.web.controller.order;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.hk.commons.utils.MsgTypeConstants;
import com.hk.service.IPush;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hk.Mgr.web.message.StatusCode;
import com.hk.Mgr.web.message.order.ReservationExcelRes;
import com.hk.Mgr.web.message.order.ReservationReq;
import com.hk.Mgr.web.message.order.ReservationRes;
import com.hk.base.BaseCtrl;
import com.hk.base.ResponseBase;
import com.hk.commons.Constant;
import com.hk.commons.ConstantOrderStatus;
import com.hk.commons.ConstantPush;
import com.hk.commons.DataUtil;
import com.hk.commons.DateUtil;
import com.hk.commons.ExcelHelper;
import com.hk.commons.HqlFilter;
import com.hk.commons.StringHelper;
import com.hk.commons.enm.ReservationPayStatusEnum;
import com.hk.commons.entity.Organization;
import com.hk.commons.entity.order.OrderInfo;
import com.hk.commons.entity.order.Reservation;
import com.hk.commons.entity.product.Company;
import com.hk.commons.entity.product.ProductInfo;
import com.hk.commons.entity.sys.SysUser;
import com.hk.service.IFundInfo_Yimi;
import com.hk.service.IOrganization;
import com.hk.service.order.IOrderInfo;
import com.hk.service.order.IReservation;
import com.hk.service.product.ICompany;
import com.hk.service.product.IProductInfo;
import com.hk.service.sys.ISysUser;
import com.hk.service.sys.ISysUserRoles;

@Controller
@RequestMapping(value = BaseCtrl.MgrRootPath + "/reservation")
public class ReservationCtrl {

	private Logger logger = LoggerFactory.getLogger(Reservation.class);

	@Autowired
	private IReservation reservationService;

	@Autowired
	private IOrderInfo orderService;

	@Autowired
	private ISysUser userService;

	@Autowired
	private ICompany companyService;

	@Autowired
	private IProductInfo productService;

	@Autowired
	private IFundInfo_Yimi fundInfoService;

	@Autowired
	private IOrganization orgService;

	@Autowired
	private ISysUserRoles roleService;

	@Autowired
	private IReservation reservationImpl;

	@ResponseBody
	@RequestMapping(value = "/save", method = RequestMethod.POST)
	public ResponseBase<Boolean> save(@RequestBody ReservationReq req) {
		ResponseBase<Boolean> resp = new ResponseBase<>();
		Reservation rv = new Reservation();
		SysUser user = null;
		ProductInfo prod = null;
		Long resultCode = null;

		BigDecimal bespeakAmount = req.getAmount();
		Long prodId = req.getProductId();

		String userPhoneNum = req.getUserPhoneNum();
		Integer type = req.getType();


		// 如果type = 1, 则是自己预约
		if (type == Constant.BESPEAK_TYPE_SELF) {
			user = userService.findById(req.getUserId());
		}else if ( type == Constant.BESPEAK_TYPE_OTHER) {
			user = userService.getByAccount(userPhoneNum);
		}

		// 如果用户信息存在则继续，否则报错
		if (user != null) {
			prod = productService.findById(req.getProductId());

			// 用户和产品都存在, 则保留预约信息
			if (prod != null) {
				rv.setUserId(user.getId());
				rv.setProductId(req.getProductId());
				rv.setCompanyId(prod.getIssuerId());
				// 添加操作人信息
				rv.setOperator(req.getOperator());

				// 添加理财师信息,理财师为用户默认的理财师
				SysUser financialPlanner = null;
				if (user.getRecommendCode() != null) {
					financialPlanner = userService.getByAccount(user
							.getRecommendCode());
					if (financialPlanner != null) {
						rv.setInside(financialPlanner.getId());
					}
				}
				// 添加预约金额, 设置已付款金额为0, 并且设置付款状态为未付款
				rv.setAmount(bespeakAmount);
				rv.setPayAmount(new BigDecimal(0));
				rv.setStatus(Constant.BESPEAK_SATUS_NO_PAY);

				resultCode = reservationImpl.add(rv);
			}
		}

		if (resultCode != null) {
//try {
//	sendPushToFinancial(user.getName(), user.getRealName(),
//			StringHelper.myformat.format(bespeakAmount),
//			prod.getName(), user.getRecommendCode());
//} catch (Exception e) {
//	logger.error("客户预约推送给理财师异常！",e);
//}
			
			// 订单保存成功, 则更改产品的预约金额
			productService.addBespeakAccount(prodId, bespeakAmount);

			resp.setResult(true);
			resp.setResultCode(StatusCode.SUCCESS.key());
		} else {
			String msg = "ERROR: 保存客户订单信息错误!userPhoneNum = " + userPhoneNum;

			if (user == null) {
				msg += "客户信息不存在!";
			}
			logger.error(msg);
			resp.setResult(false);
			resp.setMsg(msg);
			resp.setResultCode(StatusCode.EXCEPTION.key());
		}
		return resp;
	}

//	private void sendPushToFinancial(String custPhone, String custName,
//			String amt, String productName, String phone) {
//		// 您的客户张三 ，已成功预约1笔 50000元的盛世四海
//		if (StringHelper.isNotEmpty(phone)) {
//			String msg = ConstantPush.PUSH_APPOINT_START + custPhone + ":"
//					+ custName + ConstantPush.PUSH_APPOINT_MIDDLE + amt
//					+ ConstantPush.PUSH_APPOINT_END + productName;
//			pushService.jgPushMsg(msg, null, null, null, phone,
//					ConstantPush.PUSH_MENU_APPOINTMENT);
//		}
//
//	}

	@ResponseBody
	@RequestMapping(value = "/list", method = RequestMethod.POST)
	public ResponseBase<List<ReservationExcelRes>> list(
			@RequestBody ReservationReq req) {
		ResponseBase<List<ReservationExcelRes>> resp = new ResponseBase<>();

		if (req.getUserId() == null) {
			resp.setResultCode(StatusCode.PARAM_ERROR.key());
			resp.setMsg("请登录后再尝试！");
			return resp;
		}

		String id = null;
		String userId = null;
		if (req.getId() != null) {
			id = req.getId().toString();
		}

		userId = req.getUserId().toString();

		String userName = req.getUserName();

		String beginDateStr = req.getBeginDate();
		String endDateStr = req.getEndDate();

		Integer curPage = req.getCurPage();
		Integer pageSize = req.getPageSize();

		Long productId = req.getProductId();
		logger.info("order/list 传入的参数为" + " userName =" + req.getUserName()
				+ " productId =" + req.getProductId() + " id = " + req.getId()
				+ " beginDate =" + req.getBeginDate() + " endDate = "
				+ req.getEndDate());

		List<ReservationExcelRes> reservationExcelList = getReservation(id,
				userId, userName, productId, beginDateStr, endDateStr, curPage,
				pageSize);
		resp.setResult(reservationExcelList);
		resp.setSize(reservationExcelList.size());
		resp.setResultCode(StatusCode.SUCCESS.key());
		return resp;
	}

	@ResponseBody
	@RequestMapping(value = "/setInside")
	public ResponseBase<Boolean> setInside(@RequestBody ReservationRes res) {
		ResponseBase<Boolean> rb = new ResponseBase<>();
		Reservation rs = reservationImpl.findById(res.getId());
		// 分配的理财师ID
		rs.setInside(res.getOperator());
		// 记录操作人ID
		rs.setOperator(res.getOperator());
		rs.setUpts(System.currentTimeMillis());
		reservationImpl.update(rs);
		rb.setResult(true);
		return rb;
	}

	/**
	 * 获得所有订单信息
	 * 
	 * @author jeff
	 * @return
	 */
	@RequestMapping(value = "/excel")
	@ResponseBody
	public void excelExport(HttpServletRequest request,
			HttpServletResponse response, @RequestParam String id,
			@RequestParam String userId, @RequestParam String userName,
			@RequestParam Long productId, @RequestParam String beginDateStr,
			@RequestParam String endDateStr) {
		userId = userId.split(",")[0];
		logger.info("reservation/list 传入的参数为" + " id = " + id + " userName ="
				+ userName + " productId =" + productId + " beginDate ="
				+ beginDateStr + " endDate = " + endDateStr);

		List<ReservationExcelRes> resExcellist = getReservation(id, userId,
				userName, productId, beginDateStr, endDateStr, 0, 99999999);
		String head = "订单号,预约金额,购买金额, 预约状态,顾客编号,顾客姓名, 顾客年龄, 顾客性别, 顾客手机号,产品Id,产品Code, 产品名称,产品所属公司编码,产品所属公司名称,理财师编号,理财师名称,理财师所属的部门,理财师手机号,订单创建时间";
		ExcelHelper newExcel = new ExcelHelper(resExcellist, head);
		Workbook wb = newExcel.outputExcel();

		response.setContentType("application/vnd.ms-excel");

		String titlename = "预约订单列表";
		try {
			response.setHeader("Content-disposition", "attachment; filename="
					+ new String((titlename).getBytes("gbk"), "iso8859-1")
					+ ".xlsx");
		} catch (UnsupportedEncodingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}

		OutputStream ouputStream;
		try {
			ouputStream = response.getOutputStream();
			wb.write(ouputStream);
			ouputStream.flush();
			ouputStream.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@ResponseBody
	@RequestMapping(value = "/update")
	public ResponseBase<Boolean> update(@RequestBody ReservationReq req) {
		ResponseBase<Boolean> rb = new ResponseBase<>();

		logger.info("获取预约列表 传入的参数为" + " id = " + req.getId() + " amount = "
				+ req.getAmount() + " payAmount = " + req.getPayAmount()
				+ " productId = " + req.getProductId() + " indiderPhone ="
				+ req.getInsiderPhone() + " operator =" + req.getOperator());

		Long id = null;
		Long productId = req.getProductId();

		Reservation rs = null;
		if (StringUtils.isNotEmpty(req.getId())) {
			id = Long.valueOf(req.getId());
		}

		if (id != null) {
			rs = reservationImpl.findById(id);
		}
		// 记录操作人信息
		rs.setOperator(Long.valueOf(req.getOperator()));

		// 更改理财师信息
		if (req.getInside() != null
				&& userService.existByName(req.getInsiderPhone())) {
			rs.setInside(req.getInside());
		}

		rs.setUpts(System.currentTimeMillis());

		// 更改用户支付信息
		/**
		 * 如果用户原有的付款为0， 并且新增后的付款不为空，则新增订单记录
		 */
		BigDecimal newPayAmount = req.getPayAmount();
		BigDecimal newBespeakAmount = req.getAmount();

		BigDecimal oldPayAmount = rs.getPayAmount();
		BigDecimal oldBespeakAmount = rs.getAmount();

		if (newPayAmount != null && newBespeakAmount != null) {

			// 如果支付金额和预约金额相同，则更改支付信息为全额支付，否则为部分支付
			if (newPayAmount.compareTo(newBespeakAmount) != -1) {
				rs.setStatus(ConstantOrderStatus.PAY_STATUS_TRUE);
			} else {
				rs.setStatus(ConstantOrderStatus.PAY_STATUS_PART);
			}

			rs.setPayAmount(newPayAmount);
			rs.setAmount(newBespeakAmount);
			creatOrder(rs);
		}

		reservationImpl.update(rs);
		// 更改产品的预约金额
		productService.addBespeakAccount(productId,
				newBespeakAmount.subtract(oldBespeakAmount));

		// 更改产品的付款金额
		productService.addYraiseAccount(productId,
				newPayAmount.subtract(oldPayAmount));

		rb.setResultCode(StatusCode.SUCCESS.key());
		rb.setMsg("更改预约信息成功！");
		rb.setResult(true);
		return rb;
	}

	/**
	 * 根据预约信息生成订单
	 * 
	 * @param rs
	 *            产品预约信息
	 * @return True/False
	 */
	public boolean creatOrder(Reservation rs) {
		boolean t = false;
		OrderInfo order = new OrderInfo();
		// 添加产品信息
		order.setProductId(rs.getProductId());
		order.setCompanyId(rs.getCompanyId());

		// 在订单中保存预约订单号
		order.setBrokerOrderNo(rs.getId().toString());
		// 添加理财师理财师ID
		order.setFinancialPlannerId(rs.getInside());

		// 添加购买人信息
		order.setUserId(rs.getUserId());

		// 添加确认状态
		order.setConfirmStatus(ConstantOrderStatus.CONFIRM_STATUS__TRUE);

		// 添加订单支付状态
		order.setPayStatus(ConstantOrderStatus.PAY_STATUS_TRUE);

		// 添加用户的支付金额
		order.setSuccessAmount(rs.getPayAmount());
		orderService.add(order);
		return t;

	}

	private List<ReservationExcelRes> getReservation(String id, String userId,
			String userName, Long productId, String beginDateStr,
			String endDateStr, Integer curPage, Integer pageSize) {

		// 如果不是 运营部的人员，则进行datamasking
		Boolean isOpear = roleService
				.isOperationalManager(Long.valueOf(userId));

		List<ReservationExcelRes> reservationExcellist = new ArrayList<>();

		logger.info("获取预约列表 传入的参数为" + " id = " + id + " userName =" + userName
				+ " productId =" + productId + " beginDate =" + beginDateStr
				+ " endDate = " + endDateStr + " userId = " + userId
				+ "  isOpear = " + isOpear);

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

		Date beginDate;
		Date endDate;

		HqlFilter hqlFilter = new HqlFilter();

		hqlFilter.addSql(" where 1=1 ");
		try {
			if (StringUtils.isNotEmpty(beginDateStr)) {
				beginDate = format.parse(beginDateStr);
				hqlFilter.addSql(" and cts > " + beginDate.getTime());
			}
			if (StringUtils.isNotEmpty(endDateStr)) {
				endDate = format.parse(endDateStr);
				Long endTimeLong = endDate.getTime() + 60 * 60 * 24 * 1000;
				hqlFilter.addSql(" and cts < " + endTimeLong);
			}
		} catch (ParseException e1) {
			logger.error("reservation/list 日期格式转换错误",e1);
		}

		if (id != null && id.length() > 10) {
			hqlFilter.addEQFilter("id", Long.valueOf(id));
		} else {

			// 如果不是运营部的人员，则添加筛选条件
			if (!isOpear) {
				SysUser user = userService.findById(Long.valueOf(userId));

				// 增加组织架构的筛选
				if (user.getOrgId() != null) {
					Organization org = orgService.findById(user.getOrgId());
					// 如果用户的组织架构不为空，且为部门负责人
					if (org != null && org.getIsHeader() == 1) {
						String code = orgService.getOrgLeaderCodeByOrgId(org
								.getId());
						hqlFilter
								.addSql(" and inside in (select id from SysUser where orgId in (select id from  Organization where code like '"
										+ code + "%'))");
					} else {
						hqlFilter.addSql(" and ( userId = " + userId
								+ " or inside = " + userId + " )");
					}
				}
			}

			if (StringUtils.isNotEmpty(userName)) {
				hqlFilter
						.addSql(" and userId in ( select id  from  SysUser where name like '%"
								+ userName
								+ "%\' "
								+ "or RealName like  '%"
								+ userName + "%\') ");
			}

			if (productId != null) {
				hqlFilter.addEQFilter("productId", productId);
			}

		}

		hqlFilter.addSort("cts");
		hqlFilter.addOrder("desc");
		logger.info("筛选条件是" + hqlFilter.getWhereHql());
		List<Reservation> reservationList = reservationService.findByFilter(
				hqlFilter, curPage, pageSize);

		for (Reservation reservation : reservationList) {
			ReservationExcelRes reservationExcelRes = new ReservationExcelRes();
			// 添加订单直接相关的属性
			reservationExcelRes.setCol01id(reservation.getId().toString());

			if (reservation.getAmount() != null) {
				reservationExcelRes.setCol02amount(reservation.getAmount()
						.toString());
			} else {
				reservationExcelRes.setCol02amount(new BigDecimal("0.00")
						.toString());
			}

			if (reservation.getPayAmount() != null) {
				reservationExcelRes.setCol03payAmount(reservation
						.getPayAmount().toString());
			} else {
				reservationExcelRes.setCol03payAmount(new BigDecimal("0.00")
						.toString());
			}

			String reservationStatus = ReservationPayStatusEnum
					.getReservationPayStatusStr(reservation.getStatus());
			reservationExcelRes.setCol04status(reservationStatus);

			if (reservation.getCts() != null) {
				reservationExcelRes.setCol19cts(DateUtil
						.longToLongDate(reservation.getCts()));
			}
			// 添加用户相关的属性
			SysUser user = userService.findById(reservation.getUserId());
			if (user != null) {
				reservationExcelRes.setCol05userId(user.getId().toString());

				String userAge = null;
				if (user.getAge() != null) {
					userAge = user.getAge().toString();
				}

				reservationExcelRes.setCol07userAge(userAge);

				if (user.getGender() != null) {
					reservationExcelRes
							.setCol08userGender(user.getGender() == 1 ? "男"
									: "女");
				}

				if (isOpear) {
					reservationExcelRes.setCol06userName(user.getRealName());
					reservationExcelRes.setCol09userPhoneNum(user.getName());
				} else {
					String userRealName = user.getRealName();
					String encrypeUserName = DataUtil
							.getEncryptRealName(userRealName);
					reservationExcelRes.setCol06userName(encrypeUserName);

					String userPhone = user.getName();
					String encrypeUserPhone = DataUtil
							.getEncryptPhoneNum(userPhone);
					reservationExcelRes.setCol09userPhoneNum(encrypeUserPhone);
				}
			}

			// 添加产品相关的信息
			reservationExcelRes.setCol10productId(reservation.getProductId()
					.toString());
			ProductInfo prod = productService.findById(reservation
					.getProductId());
			if (prod != null) {
				reservationExcelRes.setCol11productCode(prod.getProNo());
				reservationExcelRes.setCol12productName(prod.getName());
				// 添加产品的公司信息
				Company co = companyService.findById(prod.getIssuerId());
				if (co != null) {
					reservationExcelRes.setCol13productCompanyId(co.getId()
							.toString());
					reservationExcelRes
							.setCol14productCompanyName(co.getName());
				}
			}

			// 添加理财师相关的属性
			if (reservation.getInside() != null
					&& userService.existById(reservation.getInside())) {
				SysUser inSider = userService.findById(reservation.getInside());
				reservationExcelRes.setCol15inside(inSider.getId().toString());
				reservationExcelRes.setCol16insideName(inSider.getRealName());
				if (inSider.getOrgId() != null) {
					Organization org = orgService.findById(inSider.getOrgId());
					if (org != null) {
						reservationExcelRes.setCol17insideDepName(orgService
								.getDepNameById(org.getId()));
					}
				}
				reservationExcelRes.setCol18insidePhoneNum(inSider.getName());
			}

			reservationExcellist.add(reservationExcelRes);
		}

		return reservationExcellist;
	}

	@ResponseBody
	@RequestMapping(value = "/getSize", method = RequestMethod.POST)
	public ResponseBase<Long> getSize(@RequestBody ReservationReq req) {
		ResponseBase<Long> resp = new ResponseBase<>();

		if (req.getUserId() == null) {
			resp.setResultCode(StatusCode.PARAM_ERROR.key());
			resp.setMsg("请登录后再尝试！");
			return resp;
		}

		// 如果不是 运营部的人员，则进行datamasking
		Boolean isOpear = roleService.isOperationalManager(Long.valueOf(req
				.getUserId()));

		String id = null;
		String userId = null;
		if (req.getId() != null) {
			id = req.getId().toString();
		}

		if (req.getUserId() != null) {
			userId = req.getUserId().toString();
		}

		String userName = req.getUserName();

		String beginDateStr = req.getBeginDate();
		String endDateStr = req.getEndDate();

		Long productId = req.getProductId();
		logger.info("order/list 传入的参数为" + " userName =" + req.getUserName()
				+ " productId =" + req.getProductId() + " id = " + req.getId()
				+ " beginDate =" + req.getBeginDate() + " endDate = "
				+ req.getEndDate());

		List<ReservationExcelRes> reservationExcellist = new ArrayList<>();

		logger.info("获取预约列表 传入的参数为" + " id = " + id + " userName =" + userName
				+ " productId =" + productId + " beginDate =" + beginDateStr
				+ " endDate = " + endDateStr);

		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

		Date beginDate;
		Date endDate;

		HqlFilter hqlFilter = new HqlFilter();

		hqlFilter.addSql(" where 1=1 ");
		try {
			if (StringUtils.isNotEmpty(beginDateStr)) {
				beginDate = format.parse(beginDateStr);

				hqlFilter.addSql(" and cts > " + beginDate.getTime());
			}

			if (StringUtils.isNotEmpty(beginDateStr)) {
				endDate = format.parse(endDateStr);
				hqlFilter.addSql(" and cts < " + endDate.getTime());
			}
		} catch (ParseException e1) {
			// TODO Auto-generated catch block
			logger.error("reservation/list 日期格式转换错误");
			e1.printStackTrace();
		}

		//
		if (id != null && id.length() > 10) {
			hqlFilter.addEQFilter("id", Long.valueOf(id));
		} else {

			SysUser user = userService.findById(Long.valueOf(userId));

			// 如果不是运营部的人员，则添加筛选条件
			if (!isOpear) {

				// 增加组织架构的筛选
				if (user.getOrgId() != null) {
					Organization org = orgService.findById(user.getOrgId());
					// 如果用户的组织架构不为空，且为部门负责人
					if (org != null && org.getIsHeader() == 1) {
						String code = orgService.getOrgLeaderCodeByOrgId(org
								.getId());
						hqlFilter
								.addSql(" and inside in (select id from SysUser where orgId in (select id from  Organization where code like '"
										+ code + "%'))");
					} else {
						hqlFilter.addSql(" and ( userId = " + userId
								+ " or inside = " + userId + " )");
					}
				}
			}

			if (StringUtils.isNotEmpty(userName)) {
				hqlFilter
						.addSql(" and userId in ( select id  from  SysUser where name like '%"
								+ userName
								+ "%\' "
								+ "or RealName like  '%"
								+ userName + "%\') ");
			}

			if (productId != null) {
				hqlFilter.addEQFilter("productId", productId);
			}

		}

		hqlFilter.addSort("cts");
		hqlFilter.addOrder("desc");
		logger.info("筛选条件是" + hqlFilter.getWhereHql());

		Integer totalSize = reservationService.findByFilter(hqlFilter).size();
		resp.setResult(Long.valueOf(totalSize));
		resp.setSize(totalSize);
		resp.setResultCode(StatusCode.SUCCESS.key());

		return resp;
	}
}
